package com.jspxcms.core.web.fore;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jspxcms.common.web.Servlets;
import com.jspxcms.common.web.Validations;
import com.jspxcms.core.constant.Constants;
import com.jspxcms.core.domain.*;
import com.jspxcms.core.service.NodeBufferService;
import com.jspxcms.core.service.NodeQueryService;
import com.jspxcms.core.service.UserCustomNodeService;
import com.jspxcms.core.support.Context;
import com.jspxcms.core.support.ForeContext;
import com.jspxcms.core.support.Response;
import com.jspxcms.core.support.SiteResolver;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * NodeController
 * 
 * @author liufang
 * 
 */
@Controller
public class NodeController {
	@RequestMapping(value = { "/", "/index" })
	public String index(HttpServletRequest request,
			HttpServletResponse response, org.springframework.ui.Model modelMap) {
		return index(null, request, response, modelMap);
	}

	@RequestMapping(value = Constants.SITE_PREFIX_PATH + "")
	public String index(@PathVariable String siteNumber,
			HttpServletRequest request, HttpServletResponse response,
			org.springframework.ui.Model modelMap) {
		siteResolver.resolveSite(siteNumber);
		Site site = Context.getCurrentSite();
		Response resp = new Response(request, response, modelMap);
		List<String> messages = resp.getMessages();
		Node node = query.findRoot(site.getId());
		if (!Validations.exist(node, messages, "Node", "root")) {
			return resp.badRequest();
		}
		Collection<MemberGroup> groups = Context.getCurrentGroups(request);
		Collection<Org> orgs = Context.getCurrentOrgs(request);
		if (!node.isViewPerm(groups, orgs)) {
			User user = Context.getCurrentUser();
			if (user != null) {
				return resp.forbidden();
			} else {
				return resp.unauthorized();
			}
		}
		modelMap.addAttribute("node", node);
		//对node里面的模块根据用户配置进行排序
		User user = Context.getCurrentUser();
		if (null != user) {
			getSortNodeResult(node,user.getId());
		}
		modelMap.addAttribute("text", node.getText());

		ForeContext.setData(modelMap.asMap(), request);
		String template = Servlets.getParam(request, "template");
		if (StringUtils.isNotBlank(template)) {
			return template;
		} else {
			node.setChildren(new ArrayList<Node>());
			return node.getTemplate();
		}
	}

	@RequestMapping("/node/{id:[0-9]+}")
	public String node(@PathVariable Integer id, HttpServletRequest request,
			HttpServletResponse response, org.springframework.ui.Model modelMap) {
		return node(null, id, 1, request, response, modelMap);
	}

	@RequestMapping(Constants.SITE_PREFIX_PATH + "/node/{id:[0-9]+}")
	public String node(@PathVariable String siteNumber,
			@PathVariable Integer id, HttpServletRequest request,
			HttpServletResponse response, org.springframework.ui.Model modelMap) {
		return node(siteNumber, id, 1, request, response, modelMap);
	}

	@RequestMapping("/node/{id:[0-9]+}_{page:[0-9]+}")
	public String node(@PathVariable Integer id, @PathVariable Integer page,
			HttpServletRequest request, HttpServletResponse response,
			org.springframework.ui.Model modelMap) {
		return node(null, id, page, request, response, modelMap);
	}

	@RequestMapping(Constants.SITE_PREFIX_PATH
			+ "/node/{id:[0-9]+}_{page:[0-9]+}")
	public String node(@PathVariable String siteNumber,
			@PathVariable Integer id, @PathVariable Integer page,
			HttpServletRequest request, HttpServletResponse response,
			org.springframework.ui.Model modelMap) {
		Node node = query.get(id);
		siteResolver.resolveSite(siteNumber, node);
		Site site = Context.getCurrentSite();
		Response resp = new Response(request, response, modelMap);
		List<String> messages = resp.getMessages();
		if (!Validations.exist(node, messages, "Node", id)) {
			return resp.badRequest();
		}
		if (!node.getSite().getId().equals(site.getId())) {
			site = node.getSite();
			Context.setCurrentSite(site);
		}
		Collection<MemberGroup> groups = Context.getCurrentGroups(request);
		Collection<Org> orgs = Context.getCurrentOrgs(request);

		if (!node.isViewPerm(groups, orgs)) {
			User user = Context.getCurrentUser();
			if (user != null) {
				return resp.forbidden();
			} else {
				return resp.unauthorized();
			}
		}
		String linkUrl = node.getLinkUrl();
		if (StringUtils.isNotBlank(linkUrl)) {
			return "redirect:" + linkUrl;
		}
		modelMap.addAttribute("node", node);

		modelMap.addAttribute("text", node.getText());

		Map<String, Object> data = modelMap.asMap();
		ForeContext.setData(data, request);
		ForeContext.setPage(data, page, node);
		String template = Servlets.getParam(request, "template");
		if (StringUtils.isNotBlank(template)) {
			return template;
		} else {
			return node.getTemplate();
		}
	}

	@ResponseBody
	@RequestMapping(value = { "/node_views/{id:[0-9]+}",
			Constants.SITE_PREFIX_PATH + "/node_views/{id:[0-9]+}" })
	public String views(@PathVariable Integer id) {
		return Integer.toString(bufferService.updateViews(id));
	}

	@ResponseBody
	@RequestMapping("/savecustnode")
	public Object saveCustNode(@RequestParam String custnodes,@RequestParam Integer type){
		User user = Context.getCurrentUser();
		if (null != user) {
			Integer userId = user.getId();
			JSONArray nodesArr = JSON.parseArray(custnodes);
			if (null != nodesArr || !nodesArr.isEmpty()) {
				List<UserCustomNode> list = new ArrayList<UserCustomNode>();
				for (Object node:nodesArr) {
					JSONObject jsonObject = (JSONObject)node;
					UserCustomNode userCustomNode = new UserCustomNode() ;
					userCustomNode.setNodeId((Integer)jsonObject.get("id"));
					userCustomNode.setIndex((Integer)jsonObject.get("index"));
					userCustomNode.setType(type);
					userCustomNode.setUserId(userId);
					list.add(userCustomNode);
				}
				userCustomNodeService.deleteByTypeAndUserId(type,userId);
				userCustomNodeService.saveList(list);
			}
		}
		return null;
	}

	/**
	 * 排序节点
	 * @param rootNode
     */
	private void getSortNodeResult(Node rootNode,Integer userId) {
		List<Node> firstNodeLists = rootNode.getChildren();
		List<UserCustomNode> navCustomNode = userCustomNodeService.findByTypeAndUserId(0,userId);//newsNode.getChildren();
		if (null != navCustomNode && !navCustomNode.isEmpty()) {
			sortNodeHelper(firstNodeLists,navCustomNode);
		}
		Node newsNode = null;
		//找到news
		for (Node node:firstNodeLists) {
			if ("news".equals(node.getNumber())) {
				newsNode = node;
			}
			if ("dragdata".equals(node.getNumber())) {
				newsNode = node;
			}

		}
		//找到新闻模板的保存配置
		List<UserCustomNode> newsCustomNode = userCustomNodeService.findByTypeAndUserId(1,userId);//newsNode.getChildren();
		if (null != newsCustomNode && !newsCustomNode.isEmpty() && null != newsNode && newsNode.getChildren() != null && !newsNode.getChildren().isEmpty()) {
			sortNodeHelper(newsNode.getChildren(),newsCustomNode);
		}

	}

	/**
	 * 根据节点与配置列表排序
	 * @param nodes
	 * @param userCustomNodeList
     */
	private void sortNodeHelper(List<Node> nodes,List<UserCustomNode> userCustomNodeList) {
		if (null == userCustomNodeList || userCustomNodeList.isEmpty()) {
			return;
		}
		for (Node node:nodes) {
			Integer nodeId = node.getId();
			for (UserCustomNode userCustomNode:userCustomNodeList) {
				if (nodeId == userCustomNode.getNodeId()) {
					node.setSortIndex(userCustomNode.getIndex());
					break;
				} else {
					node.setSortIndex(-1);
				}
			}
		}

		Collections.sort(nodes,new Comparator<Node>() {
			@Override
			public int compare(Node o1, Node o2) {
				return o1.getSortIndex()-o2.getSortIndex();
			}
		});
	}

	@Autowired
	private SiteResolver siteResolver;
	@Autowired
	private NodeBufferService bufferService;
	@Autowired
	private NodeQueryService query;
	@Autowired
	private UserCustomNodeService userCustomNodeService;
}
